# 使用ffmpeg压缩目录下面的所有视频
import os
import subprocess

def compress_videos(directory, width=854, height=480, single_file=False):
    """
    压缩视频文件。

    参数:
    directory (str): 要处理的视频文件路径或目录路径
    width (int): 压缩后视频的宽度，默认为854
    height (int): 压缩后视频的高度，默认为480
    single_file (bool): 是否为单个文件模式，默认为False

    功能:
    - 支持压缩单个视频文件或目录下所有视频文件
    - 使用ffmpeg将视频压缩到指定的分辨率
    - 保持音频质量，使用AAC编码，比特率为192k
    - 显示处理进度
    """
    supported_formats = ('.mp4', '.mkv', '.mov')
    width = int(width) if width > 0 else 854
    
    
    if single_file:
        # 单个文件模式
        if not directory.strip().lower().endswith(supported_formats):
            print("错误：指定的文件格式不支持")
            return
        
        input_file = directory.strip()
        output_file = os.path.join(os.path.dirname(directory), 
                                 os.path.splitext(os.path.basename(directory))[0] + f'_compressed_{width}x{height}.mp4')
        
        # 处理单个文件
        bitrate_output = subprocess.check_output(['ffprobe', '-v', 'error', '-select_streams', 'v:0', '-count_packets', '-show_entries', 'stream=bit_rate', '-of', 'csv=p=0', input_file])
        input_bitrate = int(bitrate_output.decode().strip()) if bitrate_output else 0
        
        target_bitrate = max(int(input_bitrate * 0.8), 600000)
        
        subprocess.run(['ffmpeg', '-i', input_file, '-vf', f'scale={width}:{height}', 
                        '-c:v', 'libx264', '-b:v', f'{target_bitrate}', 
                        '-c:a', 'aac', '-b:a', '192k', output_file])
        
        print(f"处理完成: 100% (1/1)")
        return
    else:
        # 目录模式
        total_files = len([f for f in os.listdir(directory) if f.lower().endswith(supported_formats)])
        processed_files = 0
        
        for file in os.listdir(directory):
            if file.lower().endswith(supported_formats):
                input_file = os.path.join(directory, file)
                output_file = os.path.join(directory, os.path.splitext(file)[0] + f'_compressed_{width}x{height}.mp4')
                
                # 使用 ffprobe 获取输入视频的比特率
                bitrate_output = subprocess.check_output(['ffprobe', '-v', 'error', '-select_streams', 'v:0', '-count_packets', '-show_entries', 'stream=bit_rate', '-of', 'csv=p=0', input_file])
                input_bitrate = int(bitrate_output.decode().strip()) if bitrate_output else 0
                
                # 计算目标比特率（减少30%）
                target_bitrate = max(int(input_bitrate * 0.8), 600000)  # 最低设置为600kbps
                
                # 使用计算得到的比特率进行压缩
                subprocess.run(['ffmpeg', '-i', input_file, '-vf', f'scale={width}:{height}', 
                                '-c:v', 'libx264', '-b:v', f'{target_bitrate}', 
                                '-c:a', 'aac', '-b:a', '192k', output_file])
                
                processed_files += 1
                progress = (processed_files / total_files) * 100
                print(f"处理进度: {progress:.2f}% ({processed_files}/{total_files})")
def cut_video(input_file = None, start_time = '00:00:00', end_time = '00:00:59', output_file = None):
    """
    剪切视频文件。

    参数:
    input_file (str): 输入视频文件的路径
    start_time (str): 剪切的开始时间，格式为 "HH:MM:SS"
    end_time (str): 剪切的结束时间，格式为 "HH:MM:SS"
    output_file (str): 输出剪切后视频文件的路径

    功能:
    - 使用ffmpeg剪切指定的视频文件
    - 保持原视频的编码格式
    - 显示剪切进度
    - 完成后打印提示信息
    """
    # 获取视频总时长
    duration = float(subprocess.check_output(['ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', input_file]).decode('utf-8').strip())
    
    # 计算剪切时长
    # 将时间字符串转换为秒数
    def time_to_seconds(time_str):
        h, m, s = map(int, time_str.split(':'))
        return h * 3600 + m * 60 + s

    start_seconds = time_to_seconds(start_time)
    end_seconds = time_to_seconds(end_time)
    cut_duration = end_seconds - start_seconds
    
    # 使用ffmpeg进行视频剪切，并显示进度
    process = subprocess.Popen(['ffmpeg', '-i', input_file, '-ss', start_time, '-to', end_time, '-c', 'copy', '-progress', 'pipe:1', output_file], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
    
    for line in process.stdout:
        if 'out_time_ms' in line:
            current_time = float(line.split('=')[1]) / 1000000  # 转换为秒
            progress = (current_time / cut_duration) * 100
            print(f"\r剪切进度: {progress:.2f}%", end='', flush=True)
    
    print("\n视频剪切完成")


if __name__ == "__main__":
    cmd = input("请输入命令(1、compress/2、cut)：")
    if cmd == "1":
        compress_videos(input("请输入视频目录路径："), int(input("请输入宽度：")), int(input("请输入高度：")),bool(input("是否为单个文件模式？(y/n)：")))
    elif cmd == "2":
        cut_video(input_file = input("请输入视频路径："), output_file=input("请输入输出路径："))